/* main.cpp
 */

#include <iostream>
#include <math.h>
#include <pthread.h>
#include <cuda.h>
#include <cutil.h>

#include "globals.h"
#include "oscillators.h"
#include "synthesiser.h"
#include "rt_playback.h"

#include <string.h>

int G_argc;
char **G_argv;

// GLOBAL VARIABLES
data_bundle shared_data_bundle;
pthread_mutex_t rt_player_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t kill_rt_player_cond = PTHREAD_COND_INITIALIZER;
int count = 0;
double duration1 = 0;
//~~~~~~~~~~~~~~~~~

void *testfunc(void *d) {
	int id = *((int*) d);
	std::cout << "hello from thread :" << id << std::endl;
	std::cout << "testfunc end\n";
	return NULL;
}

void *rt_player_launcher(void *shared_data_bundle);

int main(int argc, char *argv[]) {
	std::cout << "GPU synthesis start..." << std::endl;

	G_argc = argc;
	G_argv = argv;
//	float runtime = 0.0, prev_runtime = 0.0, tot_time = 0.0;
//	int itrs = 1;
//	float delta = 0.0;

	pthread_t rt_player_thread;
	memset(&shared_data_bundle, 0, sizeof(data_bundle));
	for (int i = 0; i < NUM_SLOTS; i++) {
		init_DeviceMem(&(shared_data_bundle.buf_d_slot[i]),
				SAMPLE_SIZE * sizeof(float));
		shared_data_bundle.buf_d_slot_mutex[i] = (pthread_mutex_t*) malloc(
				sizeof(pthread_mutex_t));
		pthread_mutex_init(shared_data_bundle.buf_d_slot_mutex[i], NULL);
		shared_data_bundle.buf_d_status[i] = SLOT_EMPTY;
	}
	shared_data_bundle.sidx=0;
	shared_data_bundle.notEmpty = (pthread_cond_t*) malloc(
			sizeof(pthread_cond_t));
	shared_data_bundle.notFull = (pthread_cond_t*) malloc(
			sizeof(pthread_cond_t));
	pthread_cond_init(shared_data_bundle.notEmpty, NULL);
	pthread_cond_init(shared_data_bundle.notFull, NULL);

	int rt_player_thread_status = pthread_create(&rt_player_thread, NULL,
			rt_player_launcher, (void*) &shared_data_bundle);
	if (rt_player_thread_status) {
		std::cout << "thread creation failed ";
	}



	syn_launcher(&shared_data_bundle, &kill_rt_player_cond);
	pthread_join(rt_player_thread, NULL);
	printf("\nduration: %lf\n", duration1);
	std::cout << "GPU synthesis end..." << std::endl;
	return 0;
}

void *rt_player_launcher(void *shared_data_bundle) {
	pthread_mutex_lock(&rt_player_mutex);

	rtPlayer *p = new rtPlayer(SAMPLE_SIZE, SAMPLE_RATE);
	p->initialize_player(&(callback), shared_data_bundle);
	p->play();

	// wait for kill playback signal
	pthread_cond_wait(&kill_rt_player_cond, &rt_player_mutex);
	std::cout << "recieved rt player kill signal\n";
	p->stop();

	pthread_mutex_unlock(&rt_player_mutex);
	return NULL;
}
